<script setup lang="ts">
import {strUtil} from 'st-common-core'
import {IconifyIcon, getIcon, loadIcon, addIcon} from '@iconify/vue'
import {Icon as IconifyIconOffline} from "@iconify/vue/offline"
import {onBeforeMount, ref, watch} from "vue"
import Error404 from '@iconify-icons/tabler/error-404'

/**
 * 组件配置选项
 */
defineOptions({
  name: 'StIconIconifyOffline',
})

/**
 * 组件参数
 */
const props = withDefaults(
  defineProps<{
    // 图标名称(包含图标集前缀)或图标数据
    icon: string | IconifyIcon;
    // 宽度
    width?: string | number;
    // 高度
    height?: string | number;
    // 颜色
    color?: string;
    // 样式
    style?: Partial<CSSStyleDeclaration> | string;
    // 如果传入的图标为图标名称字符串，则图标数据在第一次被呈现时会调用该回调函数，并向该回调函数传入呈现的图标名称参数
    load?: (name: string) => void;
  }>(),
  {
    width: '1em',
    height: '1em',
    load: () => {
    },
  }
)

// 要进行渲染的图标数据
const iconData = ref<IconifyIcon | string>(props.icon)
/**
 * 图标数据预处理
 */
const iconDataPreHandler = async () => {
  // 如果传入的图标为图标名称字符串
  if (strUtil.isStr(props.icon)) {
    // 从本地图标存储数据中获取图标数据
    iconData.value = getIcon(props.icon) as IconifyIcon
    // 如果本地图标存储中没有该图标数据，则尝试从网络获取
    if (!iconData.value) {
      iconData.value = await loadIcon(props.icon)
        .catch((err) => Promise.resolve(err))
      // 如果网络获取失败
      if (strUtil.isStr(iconData.value)) {
        // 使用 tabler:error-404 图标
        iconData.value = Error404
      } else {
        // 存储图标数据到本地图标存储
        addIcon(props.icon, iconData.value)
      }
    }
  }
}
onBeforeMount(async () => {
  await iconDataPreHandler()
})
watch(() => props.icon, async () => {
  await iconDataPreHandler()
})
</script>

<template>
  <IconifyIconOffline
    class="st-icon-iconify-offline"
    :icon="iconData"
    :width="width"
    :height="height"
    :color="color"
    :style="style"
    @load="load"
  />
</template>

<style scoped>
.st-icon-iconify-offline {
  color: inherit;
}
</style>
